package com.witdata.framework.service.docker.impl;

import com.alibaba.fastjson2.JSON;
import com.witdata.common.domain.Status;
import com.witdata.common.domain.dto.InstanceContainerDto;
import com.witdata.common.domain.docker.Container;
import com.witdata.common.domain.dto.InstanceDto;
import com.witdata.common.exception.GlobalException;
import com.witdata.framework.service.docker.DockerService;
import com.witdata.rabbit.domain.Handle;
import com.witdata.rabbit.producer.InstanceProducer;
import com.witdata.rabbit.service.InstanceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;

@Service
@Slf4j
@RequiredArgsConstructor
public class DockerServiceImpl implements DockerService {
    private final InstanceService instanceService;
    private final InstanceProducer instanceProducer;

    public Container createContainer(InstanceContainerDto instanceContainerDto) {
        InstanceContainerDto containerDto = checkName(instanceContainerDto);
        String data = instanceProducer.send(containerDto.getInstanceId(), Handle.CreateContainer, Container.builder()
                .image(containerDto.getImage())
                .name(containerDto.getName())
                .build());
        return JSON.parseObject(data, Container.class);
    }

    @Override
    public void startContainer(InstanceContainerDto instanceContainerDto) {
        InstanceContainerDto containerDto = checkName(instanceContainerDto);
        instanceProducer.send(containerDto.getInstanceId(), Handle.StartContainer, Container.builder()
                .id(containerDto.getContainerId())
                .build());
    }

    @Override
    public List<Container> getContainerList(Long instanceId) {
        InstanceDto instanceDto = instanceService.getInstanceById(instanceId);
        if (ObjectUtils.isEmpty(instanceDto)) throw new GlobalException(Status.INSTANCEISNOTEXISTS);
        if (instanceDto.getStatus().equals(InstanceDto.Status.Offline)) throw new GlobalException(Status.INSTANCEOFFLINE);
        String data = instanceProducer.send(instanceId, Handle.GetContainerList, Container.builder()
                .build());
        return JSON.parseArray(data, Container.class);
    }

    @Override
    @Transactional
    public void removeContainer(InstanceContainerDto instanceContainerDto) {
        InstanceContainerDto containerDto = checkName(instanceContainerDto);
        instanceProducer.send(containerDto.getInstanceId(), Handle.RemoveContainer, Container.builder()
                .id(containerDto.getContainerId())
                .build());
    }

    @Override
    public void stopContainer(InstanceContainerDto instanceContainerDto) {
        InstanceContainerDto containerDto = checkName(instanceContainerDto);
        instanceProducer.send(containerDto.getInstanceId(), Handle.StopContainer, Container.builder()
                .id(containerDto.getContainerId())
                .build());
    }

    public InstanceContainerDto checkName(InstanceContainerDto instanceContainerDto) {
        if (!StringUtils.hasText(instanceContainerDto.getName())) {
            instanceContainerDto.setName(UUID.randomUUID().toString().replaceAll("-", ""));
        }
        return instanceContainerDto;
    }
}
